/*
 * Copyright (C) 2011  Xu Haojie
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package net.poemcode.gzlib;

import java.util.ArrayList;
import java.util.List;

import net.poemcode.gzlib.search.SearchRequest;
import net.poemcode.gzlib.search.SearchResult;
import net.poemcode.gzlib.search.SearchThread;
import android.app.Dialog;
import android.app.ExpandableListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

public class ResultActivity extends ExpandableListActivity implements OnTouchListener, OnGestureListener {

	private ExpandableListAdapter mAdapter;
	private String[] mBookKeys;
	private SearchRequest mRequest;
	private GestureDetector mDetector; 
	
	private int mTotalPageNum;
	
	private View mFooterView;
	private View mHeaderView;
	
	private static final int FLING_MIN_DISTANCE = 100;
	private static final int FLING_MIN_VELOCITY = 200;
	private static final int DIALOG_WAIT_ID = 0;
	
	private final Handler mHandler = new Handler() {

		@SuppressWarnings("unchecked")
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case SearchThread.MSG_SEARCH_ID:
				ResultActivity.this.dismissDialog(DIALOG_WAIT_ID);
				
				List<SearchResult> list;
				if (msg.obj == null) {
					list = new ArrayList<SearchResult>();
				} else {
					list = (List<SearchResult>) msg.obj;
					mTotalPageNum = msg.arg1;
					if (Integer.valueOf(mRequest.getPageNo()) == mTotalPageNum) {
						mFooterView.setVisibility(View.GONE);
					} else {
						mFooterView.setVisibility(View.VISIBLE);
					}
					if (Integer.valueOf(mRequest.getPageNo()) == 1) {
						mHeaderView.setVisibility(View.GONE);
					} else {
						mHeaderView.setVisibility(View.VISIBLE);
					}
				}
				mAdapter = new ResultExpandableListAdapter(new ArrayList<SearchResult>(list));
		        setListAdapter(mAdapter);
		        
				break;
			default:
				break;
			}
		}
		
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.result);
		
		mDetector = new GestureDetector(this);
		mBookKeys = this.getResources().getStringArray(R.array.result_key);
		
		String val1 = this.getIntent().getStringExtra("val1");
		String bookType = this.getIntent().getStringExtra("booktype");
		mRequest = new SearchRequest();
		mRequest.setVal1(val1);
		mRequest.setBooktype(bookType);
		new Thread(new SearchThread(mHandler, mRequest)).start();
		
		final ExpandableListView listView = (ExpandableListView) findViewById(android.R.id.list);
		listView.setOnTouchListener(this);
		mFooterView = getFooterView();
		listView.addFooterView(mFooterView);
		mHeaderView = getHeaderView();
		listView.addHeaderView(mHeaderView);
		
		registerForContextMenu(getExpandableListView());
        
        waitForResponse();
	}

	private void waitForResponse() {
		mAdapter = new ResultExpandableListAdapter(new ArrayList<SearchResult>());
        setListAdapter(mAdapter);
        showDialog(DIALOG_WAIT_ID);
	}
	
	private View getHeaderView() {
		ImageButton button = new ImageButton(this);
		button.setImageResource(R.drawable.arrow_up);
		button.setBackgroundColor(android.R.color.transparent);
		button.setPadding(0, 0, 0, 0);
		button.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				trunForward();
			}
		});
		button.setVisibility(View.GONE);
		return button;
	}
	
	private View getFooterView() {
		ImageButton button = new ImageButton(this);
		button.setImageResource(R.drawable.arrow_down);
		button.setBackgroundColor(android.R.color.transparent);
		button.setPadding(0, 0, 0, 0);
		button.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				turnBackward();
			}
		});
		button.setVisibility(View.GONE);
		return button;
	}
	
	private void detailClick(int groupPos) {
		String bookrecno = String.valueOf(mAdapter.getGroupId(groupPos));
		String booktitle = String.valueOf(mAdapter.getGroup(groupPos));
		Intent intent = new Intent("net.poemcode.gzlib.DETAIL");
		intent.putExtra("bookrecno", bookrecno);
		intent.putExtra("booktitle", booktitle);
		startActivity(intent);
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DIALOG_WAIT_ID:
			ProgressDialog dialog = ProgressDialog.show(this, "", "Loading. Please wait...", true);
			return dialog;
		default:
			return null;	
		}
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		menu.setHeaderTitle(R.string.detail_title);
        menu.add(0, 0, 0, R.string.detail_action);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item
				.getMenuInfo();

		int type = ExpandableListView.getPackedPositionType(info.packedPosition);
		switch (type) {
		case ExpandableListView.PACKED_POSITION_TYPE_CHILD:
		case ExpandableListView.PACKED_POSITION_TYPE_GROUP:
			int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
			detailClick(groupPos);
			return true;
		default:
			return false;
		}
	}


	@Override
	public boolean onDown(MotionEvent arg0) {
		// do nothing
		return false;
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE
				&& Math.abs(velocityX) > FLING_MIN_VELOCITY) {
			// Fling left
			turnBackward();
		} else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE
				&& Math.abs(velocityX) > FLING_MIN_VELOCITY) {
			// Fling right
			trunForward();
		}
		return false;
	}

	private void trunForward() {
		Integer pageNo = Integer.valueOf(mRequest.getPageNo());
		if ((pageNo-1) > 0) {
			mRequest.setPageNo(String.valueOf(pageNo - 1));
			new Thread(new SearchThread(mHandler, mRequest)).start();
			waitForResponse();
		} else {
			Toast.makeText(this, R.string.result_first_page, Toast.LENGTH_SHORT).show();
		}
	}

	private void turnBackward() {
		Integer curPageNum = Integer.valueOf(mRequest.getPageNo());
		if ((curPageNum + 1) <= mTotalPageNum) {
			mRequest.setPageNo(String.valueOf(curPageNum + 1));
			new Thread(new SearchThread(mHandler, mRequest)).start();
			waitForResponse();
		} else {
			Toast.makeText(this, R.string.result_last_page, Toast.LENGTH_SHORT).show();
		}
	}

	@Override
	public void onLongPress(MotionEvent e) {
		// do nothing
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		// do nothing
		return false;
	}

	@Override
	public void onShowPress(MotionEvent e) {
		// do nothing
	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		return false;
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		return mDetector.onTouchEvent(event);
	}
	
	private class ResultExpandableListAdapter extends BaseExpandableListAdapter {
		
		private ArrayList<SearchResult> mResultList;
		
		public ResultExpandableListAdapter(ArrayList<SearchResult> resultList) {
			this.mResultList = resultList;
		}

		@Override
		public Object getChild(int groupPosition, int childPosition) {
			SearchResult result = mResultList.get(groupPosition);
			switch (childPosition) {
			case 0:
				return mBookKeys[childPosition] + result.getAuthor();
			case 1:
				return mBookKeys[childPosition] + result.getPublisher();
			case 2:
				return mBookKeys[childPosition] + result.getPubdate();	
			case 3:
				return mBookKeys[childPosition] + result.getPage();	
			case 4:
				return mBookKeys[childPosition] + result.getIsbn();
			case 5:
				return mBookKeys[childPosition] + result.getPrice();
			default:
				return null;
			}
		}

		@Override
		public long getChildId(int groupPosition, int childPosition) {
			return childPosition;
		}

		@Override
		public View getChildView(final int groupPosition, int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
			View childView = ResultActivity.this.getLayoutInflater().inflate(R.layout.result_child, null);
			TextView titleView = (TextView) childView.findViewById(R.id.bookValue);
			titleView.setText(getChild(groupPosition, childPosition).toString());
            return childView;
		}

		@Override
		public int getChildrenCount(int groupPosition) {
			return 6;
		}

		@Override
		public Object getGroup(int groupPosition) {
			return mResultList.get(groupPosition).getTitle();
		}

		@Override
		public int getGroupCount() {
			return mResultList.size();
		}

		@Override
		public long getGroupId(int groupPosition) {
			SearchResult result = mResultList.get(groupPosition);
			return Long.valueOf(result.getBookrecno());
		}

		@Override
		public View getGroupView(final int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {
			View groupView = ResultActivity.this.getLayoutInflater().inflate(R.layout.result_group, null);
            TextView titleView = (TextView) groupView.findViewById(R.id.bookTitle);
            titleView.setText(getGroup(groupPosition).toString());
            Button titleBtn = (Button) groupView.findViewById(R.id.bookDetail);
			titleBtn.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					detailClick(groupPosition);
				}
			});
			if (isExpanded) {
				titleBtn.setVisibility(View.VISIBLE);
			} else {
				titleBtn.setVisibility(View.INVISIBLE);
			}
            return groupView;
		}

		@Override
		public boolean hasStableIds() {
			return true;
		}

		@Override
		public boolean isChildSelectable(int groupPosition, int childPosition) {
			return false;
		}
		
	}

}
